//===----------------------------------------------------------------------===//
//
// This source file is part of the Soto for AWS open source project
//
// Copyright (c) 2017-2022 the Soto project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of Soto project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//

// THIS FILE IS AUTOMATICALLY GENERATED by https://github.com/soto-project/soto-codegenerator.
// DO NOT EDIT.

import Foundation
import SotoCore

extension MWAA {
    // MARK: Enums

    public enum EnvironmentStatus: String, CustomStringConvertible, Codable, _SotoSendable {
        case available = "AVAILABLE"
        case createFailed = "CREATE_FAILED"
        case creating = "CREATING"
        case deleted = "DELETED"
        case deleting = "DELETING"
        case unavailable = "UNAVAILABLE"
        case updateFailed = "UPDATE_FAILED"
        case updating = "UPDATING"
        public var description: String { return self.rawValue }
    }

    public enum LoggingLevel: String, CustomStringConvertible, Codable, _SotoSendable {
        case critical = "CRITICAL"
        case debug = "DEBUG"
        case error = "ERROR"
        case info = "INFO"
        case warning = "WARNING"
        public var description: String { return self.rawValue }
    }

    public enum Unit: String, CustomStringConvertible, Codable, _SotoSendable {
        case bits = "Bits"
        case bitsSecond = "Bits/Second"
        case bytes = "Bytes"
        case bytesSecond = "Bytes/Second"
        case count = "Count"
        case countSecond = "Count/Second"
        case gigabits = "Gigabits"
        case gigabitsSecond = "Gigabits/Second"
        case gigabytes = "Gigabytes"
        case gigabytesSecond = "Gigabytes/Second"
        case kilobits = "Kilobits"
        case kilobitsSecond = "Kilobits/Second"
        case kilobytes = "Kilobytes"
        case kilobytesSecond = "Kilobytes/Second"
        case megabits = "Megabits"
        case megabitsSecond = "Megabits/Second"
        case megabytes = "Megabytes"
        case megabytesSecond = "Megabytes/Second"
        case microseconds = "Microseconds"
        case milliseconds = "Milliseconds"
        case none = "None"
        case percent = "Percent"
        case seconds = "Seconds"
        case terabits = "Terabits"
        case terabitsSecond = "Terabits/Second"
        case terabytes = "Terabytes"
        case terabytesSecond = "Terabytes/Second"
        public var description: String { return self.rawValue }
    }

    public enum UpdateStatus: String, CustomStringConvertible, Codable, _SotoSendable {
        case failed = "FAILED"
        case pending = "PENDING"
        case success = "SUCCESS"
        public var description: String { return self.rawValue }
    }

    public enum WebserverAccessMode: String, CustomStringConvertible, Codable, _SotoSendable {
        case privateOnly = "PRIVATE_ONLY"
        case publicOnly = "PUBLIC_ONLY"
        public var description: String { return self.rawValue }
    }

    // MARK: Shapes

    public struct CreateCliTokenRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "name", location: .uri("Name"))
        ]

        /// The name of the Amazon MWAA environment. For example, MyMWAAEnvironment.
        public let name: String

        public init(name: String) {
            self.name = name
        }

        public func validate(name: String) throws {
            try self.validate(self.name, name: "name", parent: name, max: 80)
            try self.validate(self.name, name: "name", parent: name, min: 1)
            try self.validate(self.name, name: "name", parent: name, pattern: "^[a-zA-Z][0-9a-zA-Z-_]*$")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct CreateCliTokenResponse: AWSDecodableShape {
        /// An Airflow CLI login token.
        public let cliToken: String?
        /// The Airflow web server hostname for the environment.
        public let webServerHostname: String?

        public init(cliToken: String? = nil, webServerHostname: String? = nil) {
            self.cliToken = cliToken
            self.webServerHostname = webServerHostname
        }

        private enum CodingKeys: String, CodingKey {
            case cliToken = "CliToken"
            case webServerHostname = "WebServerHostname"
        }
    }

    public struct CreateEnvironmentInput: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "name", location: .uri("Name"))
        ]

        /// A list of key-value pairs containing the Apache Airflow configuration options you want to attach to your environment. To learn more, see Apache Airflow configuration options.
        public let airflowConfigurationOptions: [String: String]?
        /// The Apache Airflow version for your environment. If no value is specified, it defaults to the latest version. Valid values: 1.10.12, 2.0.2, and 2.2.2. To learn more, see Apache Airflow versions on Amazon Managed Workflows for Apache Airflow (MWAA).
        public let airflowVersion: String?
        /// The relative path to the DAGs folder on your Amazon S3 bucket. For example, dags. To learn more, see Adding or updating DAGs.
        public let dagS3Path: String
        /// The environment class type. Valid values: mw1.small, mw1.medium, mw1.large. To learn more, see Amazon MWAA environment class.
        public let environmentClass: String?
        /// The Amazon Resource Name (ARN) of the execution role for your environment. An execution role is an Amazon Web Services Identity and Access Management (IAM) role that grants MWAA permission to access Amazon Web Services services and resources used by your environment. For example, arn:aws:iam::123456789:role/my-execution-role. To learn more, see Amazon MWAA Execution role.
        public let executionRoleArn: String
        /// The Amazon Web Services Key Management Service (KMS) key to encrypt the data in your environment. You can use an Amazon Web Services owned CMK, or a Customer managed CMK (advanced). To learn more, see Create an Amazon MWAA environment.
        public let kmsKey: String?
        /// Defines the Apache Airflow logs to send to CloudWatch Logs.
        public let loggingConfiguration: LoggingConfigurationInput?
        /// The maximum number of workers that you want to run in your environment. MWAA scales the number of Apache Airflow workers up to the number you specify in the MaxWorkers field. For example, 20. When there are no more tasks running, and no more in the queue, MWAA disposes of the extra workers leaving the one worker that is included with your environment, or the number you specify in MinWorkers.
        public let maxWorkers: Int?
        /// The minimum number of workers that you want to run in your environment. MWAA scales the number of Apache Airflow workers up to the number you specify in the MaxWorkers field. When there are no more tasks running, and no more in the queue, MWAA disposes of the extra workers leaving the worker count you specify in the MinWorkers field. For example, 2.
        public let minWorkers: Int?
        /// The name of the Amazon MWAA environment. For example, MyMWAAEnvironment.
        public let name: String
        /// The VPC networking components used to secure and enable network traffic between the Amazon Web Services resources for your environment. To learn more, see About networking on Amazon MWAA.
        public let networkConfiguration: NetworkConfiguration
        /// The version of the plugins.zip file on your Amazon S3 bucket. A version must be specified each time a plugins.zip file is updated. To learn more, see How S3 Versioning works.
        public let pluginsS3ObjectVersion: String?
        /// The relative path to the plugins.zip file on your Amazon S3 bucket. For example, plugins.zip. If specified, then the plugins.zip version is required. To learn more, see Installing custom plugins.
        public let pluginsS3Path: String?
        /// The version of the requirements.txt file on your Amazon S3 bucket. A version must be specified each time a requirements.txt file is updated. To learn more, see How S3 Versioning works.
        public let requirementsS3ObjectVersion: String?
        /// The relative path to the requirements.txt file on your Amazon S3 bucket. For example, requirements.txt. If specified, then a file version is required. To learn more, see Installing Python dependencies.
        public let requirementsS3Path: String?
        /// The number of Apache Airflow schedulers to run in your environment. Valid values:   v2 - Accepts between 2 to 5. Defaults to 2.   v1 - Accepts 1.
        public let schedulers: Int?
        /// The Amazon Resource Name (ARN) of the Amazon S3 bucket where your DAG code and supporting files are stored. For example, arn:aws:s3:::my-airflow-bucket-unique-name. To learn more, see Create an Amazon S3 bucket for Amazon MWAA.
        public let sourceBucketArn: String
        /// The key-value tag pairs you want to associate to your environment. For example, "Environment": "Staging". To learn more, see Tagging Amazon Web Services resources.
        public let tags: [String: String]?
        /// The Apache Airflow Web server access mode. To learn more, see Apache Airflow access modes.
        public let webserverAccessMode: WebserverAccessMode?
        /// The day and time of the week in Coordinated Universal Time (UTC) 24-hour standard time to start weekly maintenance updates of your environment in the following format: DAY:HH:MM. For example: TUE:03:30. You can specify a start time in 30 minute increments only.
        public let weeklyMaintenanceWindowStart: String?

        public init(airflowConfigurationOptions: [String: String]? = nil, airflowVersion: String? = nil, dagS3Path: String, environmentClass: String? = nil, executionRoleArn: String, kmsKey: String? = nil, loggingConfiguration: LoggingConfigurationInput? = nil, maxWorkers: Int? = nil, minWorkers: Int? = nil, name: String, networkConfiguration: NetworkConfiguration, pluginsS3ObjectVersion: String? = nil, pluginsS3Path: String? = nil, requirementsS3ObjectVersion: String? = nil, requirementsS3Path: String? = nil, schedulers: Int? = nil, sourceBucketArn: String, tags: [String: String]? = nil, webserverAccessMode: WebserverAccessMode? = nil, weeklyMaintenanceWindowStart: String? = nil) {
            self.airflowConfigurationOptions = airflowConfigurationOptions
            self.airflowVersion = airflowVersion
            self.dagS3Path = dagS3Path
            self.environmentClass = environmentClass
            self.executionRoleArn = executionRoleArn
            self.kmsKey = kmsKey
            self.loggingConfiguration = loggingConfiguration
            self.maxWorkers = maxWorkers
            self.minWorkers = minWorkers
            self.name = name
            self.networkConfiguration = networkConfiguration
            self.pluginsS3ObjectVersion = pluginsS3ObjectVersion
            self.pluginsS3Path = pluginsS3Path
            self.requirementsS3ObjectVersion = requirementsS3ObjectVersion
            self.requirementsS3Path = requirementsS3Path
            self.schedulers = schedulers
            self.sourceBucketArn = sourceBucketArn
            self.tags = tags
            self.webserverAccessMode = webserverAccessMode
            self.weeklyMaintenanceWindowStart = weeklyMaintenanceWindowStart
        }

        public func validate(name: String) throws {
            try self.airflowConfigurationOptions?.forEach {
                try validate($0.key, name: "airflowConfigurationOptions.key", parent: name, max: 64)
                try validate($0.key, name: "airflowConfigurationOptions.key", parent: name, min: 1)
                try validate($0.key, name: "airflowConfigurationOptions.key", parent: name, pattern: "^[a-z]+([a-z0-9._]*[a-z0-9_]+)?$")
                try validate($0.value, name: "airflowConfigurationOptions[\"\($0.key)\"]", parent: name, max: 65536)
                try validate($0.value, name: "airflowConfigurationOptions[\"\($0.key)\"]", parent: name, min: 1)
                try validate($0.value, name: "airflowConfigurationOptions[\"\($0.key)\"]", parent: name, pattern: "^[ -~]+$")
            }
            try self.validate(self.airflowVersion, name: "airflowVersion", parent: name, max: 32)
            try self.validate(self.airflowVersion, name: "airflowVersion", parent: name, min: 1)
            try self.validate(self.airflowVersion, name: "airflowVersion", parent: name, pattern: "^[0-9a-z.]+$")
            try self.validate(self.dagS3Path, name: "dagS3Path", parent: name, max: 1024)
            try self.validate(self.dagS3Path, name: "dagS3Path", parent: name, min: 1)
            try self.validate(self.dagS3Path, name: "dagS3Path", parent: name, pattern: ".*")
            try self.validate(self.environmentClass, name: "environmentClass", parent: name, max: 1024)
            try self.validate(self.environmentClass, name: "environmentClass", parent: name, min: 1)
            try self.validate(self.executionRoleArn, name: "executionRoleArn", parent: name, max: 1224)
            try self.validate(self.executionRoleArn, name: "executionRoleArn", parent: name, min: 1)
            try self.validate(self.executionRoleArn, name: "executionRoleArn", parent: name, pattern: "^arn:aws(-[a-z]+)?:iam::\\d{12}:role/?[a-zA-Z_0-9+=,.@\\-_/]+$")
            try self.validate(self.kmsKey, name: "kmsKey", parent: name, max: 1224)
            try self.validate(self.kmsKey, name: "kmsKey", parent: name, min: 1)
            try self.validate(self.kmsKey, name: "kmsKey", parent: name, pattern: "^(((arn:aws(-[a-z]+)?:kms:[a-z]{2}-[a-z]+-\\d:\\d+:)?key\\/)?[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}|(arn:aws(-[a-z]+)?:kms:[a-z]{2}-[a-z]+-\\d:\\d+:)?alias/.+)$")
            try self.validate(self.maxWorkers, name: "maxWorkers", parent: name, min: 1)
            try self.validate(self.minWorkers, name: "minWorkers", parent: name, min: 1)
            try self.validate(self.name, name: "name", parent: name, max: 80)
            try self.validate(self.name, name: "name", parent: name, min: 1)
            try self.validate(self.name, name: "name", parent: name, pattern: "^[a-zA-Z][0-9a-zA-Z-_]*$")
            try self.networkConfiguration.validate(name: "\(name).networkConfiguration")
            try self.validate(self.pluginsS3ObjectVersion, name: "pluginsS3ObjectVersion", parent: name, max: 1024)
            try self.validate(self.pluginsS3ObjectVersion, name: "pluginsS3ObjectVersion", parent: name, min: 1)
            try self.validate(self.pluginsS3Path, name: "pluginsS3Path", parent: name, max: 1024)
            try self.validate(self.pluginsS3Path, name: "pluginsS3Path", parent: name, min: 1)
            try self.validate(self.pluginsS3Path, name: "pluginsS3Path", parent: name, pattern: ".*")
            try self.validate(self.requirementsS3ObjectVersion, name: "requirementsS3ObjectVersion", parent: name, max: 1024)
            try self.validate(self.requirementsS3ObjectVersion, name: "requirementsS3ObjectVersion", parent: name, min: 1)
            try self.validate(self.requirementsS3Path, name: "requirementsS3Path", parent: name, max: 1024)
            try self.validate(self.requirementsS3Path, name: "requirementsS3Path", parent: name, min: 1)
            try self.validate(self.requirementsS3Path, name: "requirementsS3Path", parent: name, pattern: ".*")
            try self.validate(self.schedulers, name: "schedulers", parent: name, max: 5)
            try self.validate(self.sourceBucketArn, name: "sourceBucketArn", parent: name, max: 1224)
            try self.validate(self.sourceBucketArn, name: "sourceBucketArn", parent: name, min: 1)
            try self.validate(self.sourceBucketArn, name: "sourceBucketArn", parent: name, pattern: "^arn:aws(-[a-z]+)?:s3:::[a-z0-9.\\-]+$")
            try self.tags?.forEach {
                try validate($0.key, name: "tags.key", parent: name, max: 128)
                try validate($0.key, name: "tags.key", parent: name, min: 1)
                try validate($0.key, name: "tags.key", parent: name, pattern: "^([\\p{L}\\p{Z}\\p{N}_.:/=+\\-@]*)$")
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, max: 256)
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, min: 1)
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, pattern: "^([\\p{L}\\p{Z}\\p{N}_.:/=+\\-@]*)$")
            }
            try self.validate(self.tags, name: "tags", parent: name, max: 50)
            try self.validate(self.tags, name: "tags", parent: name, min: 1)
            try self.validate(self.weeklyMaintenanceWindowStart, name: "weeklyMaintenanceWindowStart", parent: name, max: 9)
            try self.validate(self.weeklyMaintenanceWindowStart, name: "weeklyMaintenanceWindowStart", parent: name, min: 1)
            try self.validate(self.weeklyMaintenanceWindowStart, name: "weeklyMaintenanceWindowStart", parent: name, pattern: "(MON|TUE|WED|THU|FRI|SAT|SUN):([01]\\d|2[0-3]):(00|30)")
        }

        private enum CodingKeys: String, CodingKey {
            case airflowConfigurationOptions = "AirflowConfigurationOptions"
            case airflowVersion = "AirflowVersion"
            case dagS3Path = "DagS3Path"
            case environmentClass = "EnvironmentClass"
            case executionRoleArn = "ExecutionRoleArn"
            case kmsKey = "KmsKey"
            case loggingConfiguration = "LoggingConfiguration"
            case maxWorkers = "MaxWorkers"
            case minWorkers = "MinWorkers"
            case networkConfiguration = "NetworkConfiguration"
            case pluginsS3ObjectVersion = "PluginsS3ObjectVersion"
            case pluginsS3Path = "PluginsS3Path"
            case requirementsS3ObjectVersion = "RequirementsS3ObjectVersion"
            case requirementsS3Path = "RequirementsS3Path"
            case schedulers = "Schedulers"
            case sourceBucketArn = "SourceBucketArn"
            case tags = "Tags"
            case webserverAccessMode = "WebserverAccessMode"
            case weeklyMaintenanceWindowStart = "WeeklyMaintenanceWindowStart"
        }
    }

    public struct CreateEnvironmentOutput: AWSDecodableShape {
        /// The Amazon Resource Name (ARN) returned in the response for the environment.
        public let arn: String?

        public init(arn: String? = nil) {
            self.arn = arn
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "Arn"
        }
    }

    public struct CreateWebLoginTokenRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "name", location: .uri("Name"))
        ]

        /// The name of the Amazon MWAA environment. For example, MyMWAAEnvironment.
        public let name: String

        public init(name: String) {
            self.name = name
        }

        public func validate(name: String) throws {
            try self.validate(self.name, name: "name", parent: name, max: 80)
            try self.validate(self.name, name: "name", parent: name, min: 1)
            try self.validate(self.name, name: "name", parent: name, pattern: "^[a-zA-Z][0-9a-zA-Z-_]*$")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct CreateWebLoginTokenResponse: AWSDecodableShape {
        /// The Airflow web server hostname for the environment.
        public let webServerHostname: String?
        /// An Airflow web server login token.
        public let webToken: String?

        public init(webServerHostname: String? = nil, webToken: String? = nil) {
            self.webServerHostname = webServerHostname
            self.webToken = webToken
        }

        private enum CodingKeys: String, CodingKey {
            case webServerHostname = "WebServerHostname"
            case webToken = "WebToken"
        }
    }

    public struct DeleteEnvironmentInput: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "name", location: .uri("Name"))
        ]

        /// The name of the Amazon MWAA environment. For example, MyMWAAEnvironment.
        public let name: String

        public init(name: String) {
            self.name = name
        }

        public func validate(name: String) throws {
            try self.validate(self.name, name: "name", parent: name, max: 80)
            try self.validate(self.name, name: "name", parent: name, min: 1)
            try self.validate(self.name, name: "name", parent: name, pattern: "^[a-zA-Z][0-9a-zA-Z-_]*$")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct DeleteEnvironmentOutput: AWSDecodableShape {
        public init() {}
    }

    public struct Dimension: AWSEncodableShape {
        ///  Internal only. The name of the dimension.
        public let name: String
        ///  Internal only. The value of the dimension.
        public let value: String

        public init(name: String, value: String) {
            self.name = name
            self.value = value
        }

        private enum CodingKeys: String, CodingKey {
            case name = "Name"
            case value = "Value"
        }
    }

    public struct Environment: AWSDecodableShape {
        /// A list of key-value pairs containing the Apache Airflow configuration options attached to your environment. To learn more, see Apache Airflow configuration options.
        public let airflowConfigurationOptions: [String: String]?
        /// The Apache Airflow version on your environment. Valid values: 1.10.12, 2.0.2, and 2.2.2.
        public let airflowVersion: String?
        /// The Amazon Resource Name (ARN) of the Amazon MWAA environment.
        public let arn: String?
        /// The day and time the environment was created.
        public let createdAt: Date?
        /// The relative path to the DAGs folder on your Amazon S3 bucket. For example, dags. To learn more, see Adding or updating DAGs.
        public let dagS3Path: String?
        /// The environment class type. Valid values: mw1.small, mw1.medium, mw1.large. To learn more, see Amazon MWAA environment class.
        public let environmentClass: String?
        /// The Amazon Resource Name (ARN) of the execution role in IAM that allows MWAA to access Amazon Web Services resources in your environment. For example, arn:aws:iam::123456789:role/my-execution-role. To learn more, see Amazon MWAA Execution role.
        public let executionRoleArn: String?
        /// The Amazon Web Services Key Management Service (KMS) encryption key used to encrypt the data in your environment.
        public let kmsKey: String?
        /// The status of the last update on the environment.
        public let lastUpdate: LastUpdate?
        /// The Apache Airflow logs published to CloudWatch Logs.
        public let loggingConfiguration: LoggingConfiguration?
        /// The maximum number of workers that run in your environment. For example, 20.
        public let maxWorkers: Int?
        /// The minimum number of workers that run in your environment. For example, 2.
        public let minWorkers: Int?
        /// The name of the Amazon MWAA environment. For example, MyMWAAEnvironment.
        public let name: String?
        /// Describes the VPC networking components used to secure and enable network traffic between the Amazon Web Services resources for your environment. To learn more, see About networking on Amazon MWAA.
        public let networkConfiguration: NetworkConfiguration?
        /// The version of the plugins.zip file on your Amazon S3 bucket. To learn more, see Installing custom plugins.
        public let pluginsS3ObjectVersion: String?
        /// The relative path to the plugins.zip file on your Amazon S3 bucket. For example, plugins.zip. To learn more, see Installing custom plugins.
        public let pluginsS3Path: String?
        /// The version of the requirements.txt file on your Amazon S3 bucket. To learn more, see Installing Python dependencies.
        public let requirementsS3ObjectVersion: String?
        /// The relative path to the requirements.txt file on your Amazon S3 bucket. For example, requirements.txt. To learn more, see Installing Python dependencies.
        public let requirementsS3Path: String?
        /// The number of Apache Airflow schedulers that run in your Amazon MWAA environment.
        public let schedulers: Int?
        /// The Amazon Resource Name (ARN) for the service-linked role of the environment. To learn more, see Amazon MWAA Service-linked role.
        public let serviceRoleArn: String?
        /// The Amazon Resource Name (ARN) of the Amazon S3 bucket where your DAG code and supporting files are stored. For example, arn:aws:s3:::my-airflow-bucket-unique-name. To learn more, see Create an Amazon S3 bucket for Amazon MWAA.
        public let sourceBucketArn: String?
        /// The status of the Amazon MWAA environment. Valid values:    CREATING - Indicates the request to create the environment is in progress.    CREATE_FAILED - Indicates the request to create the environment failed, and the environment could not be created.    AVAILABLE - Indicates the request was successful and the environment is ready to use.    UPDATING - Indicates the request to update the environment is in progress.    DELETING - Indicates the request to delete the environment is in progress.    DELETED - Indicates the request to delete the environment is complete, and the environment has been deleted.    UNAVAILABLE - Indicates the request failed, but the environment was unable to rollback and is not in a stable state.    UPDATE_FAILED - Indicates the request to update the environment failed, and the environment has rolled back successfully and is ready to use.   We recommend reviewing our troubleshooting guide for a list of common errors and their solutions. To learn more, see Amazon MWAA troubleshooting.
        public let status: EnvironmentStatus?
        /// The key-value tag pairs associated to your environment. For example, "Environment": "Staging". To learn more, see Tagging Amazon Web Services resources.
        public let tags: [String: String]?
        /// The Apache Airflow Web server access mode. To learn more, see Apache Airflow access modes.
        public let webserverAccessMode: WebserverAccessMode?
        /// The Apache Airflow Web server host name for the Amazon MWAA environment. To learn more, see Accessing the Apache Airflow UI.
        public let webserverUrl: String?
        /// The day and time of the week in Coordinated Universal Time (UTC) 24-hour standard time that weekly maintenance updates are scheduled. For example: TUE:03:30.
        public let weeklyMaintenanceWindowStart: String?

        public init(airflowConfigurationOptions: [String: String]? = nil, airflowVersion: String? = nil, arn: String? = nil, createdAt: Date? = nil, dagS3Path: String? = nil, environmentClass: String? = nil, executionRoleArn: String? = nil, kmsKey: String? = nil, lastUpdate: LastUpdate? = nil, loggingConfiguration: LoggingConfiguration? = nil, maxWorkers: Int? = nil, minWorkers: Int? = nil, name: String? = nil, networkConfiguration: NetworkConfiguration? = nil, pluginsS3ObjectVersion: String? = nil, pluginsS3Path: String? = nil, requirementsS3ObjectVersion: String? = nil, requirementsS3Path: String? = nil, schedulers: Int? = nil, serviceRoleArn: String? = nil, sourceBucketArn: String? = nil, status: EnvironmentStatus? = nil, tags: [String: String]? = nil, webserverAccessMode: WebserverAccessMode? = nil, webserverUrl: String? = nil, weeklyMaintenanceWindowStart: String? = nil) {
            self.airflowConfigurationOptions = airflowConfigurationOptions
            self.airflowVersion = airflowVersion
            self.arn = arn
            self.createdAt = createdAt
            self.dagS3Path = dagS3Path
            self.environmentClass = environmentClass
            self.executionRoleArn = executionRoleArn
            self.kmsKey = kmsKey
            self.lastUpdate = lastUpdate
            self.loggingConfiguration = loggingConfiguration
            self.maxWorkers = maxWorkers
            self.minWorkers = minWorkers
            self.name = name
            self.networkConfiguration = networkConfiguration
            self.pluginsS3ObjectVersion = pluginsS3ObjectVersion
            self.pluginsS3Path = pluginsS3Path
            self.requirementsS3ObjectVersion = requirementsS3ObjectVersion
            self.requirementsS3Path = requirementsS3Path
            self.schedulers = schedulers
            self.serviceRoleArn = serviceRoleArn
            self.sourceBucketArn = sourceBucketArn
            self.status = status
            self.tags = tags
            self.webserverAccessMode = webserverAccessMode
            self.webserverUrl = webserverUrl
            self.weeklyMaintenanceWindowStart = weeklyMaintenanceWindowStart
        }

        private enum CodingKeys: String, CodingKey {
            case airflowConfigurationOptions = "AirflowConfigurationOptions"
            case airflowVersion = "AirflowVersion"
            case arn = "Arn"
            case createdAt = "CreatedAt"
            case dagS3Path = "DagS3Path"
            case environmentClass = "EnvironmentClass"
            case executionRoleArn = "ExecutionRoleArn"
            case kmsKey = "KmsKey"
            case lastUpdate = "LastUpdate"
            case loggingConfiguration = "LoggingConfiguration"
            case maxWorkers = "MaxWorkers"
            case minWorkers = "MinWorkers"
            case name = "Name"
            case networkConfiguration = "NetworkConfiguration"
            case pluginsS3ObjectVersion = "PluginsS3ObjectVersion"
            case pluginsS3Path = "PluginsS3Path"
            case requirementsS3ObjectVersion = "RequirementsS3ObjectVersion"
            case requirementsS3Path = "RequirementsS3Path"
            case schedulers = "Schedulers"
            case serviceRoleArn = "ServiceRoleArn"
            case sourceBucketArn = "SourceBucketArn"
            case status = "Status"
            case tags = "Tags"
            case webserverAccessMode = "WebserverAccessMode"
            case webserverUrl = "WebserverUrl"
            case weeklyMaintenanceWindowStart = "WeeklyMaintenanceWindowStart"
        }
    }

    public struct GetEnvironmentInput: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "name", location: .uri("Name"))
        ]

        /// The name of the Amazon MWAA environment. For example, MyMWAAEnvironment.
        public let name: String

        public init(name: String) {
            self.name = name
        }

        public func validate(name: String) throws {
            try self.validate(self.name, name: "name", parent: name, max: 80)
            try self.validate(self.name, name: "name", parent: name, min: 1)
            try self.validate(self.name, name: "name", parent: name, pattern: "^[a-zA-Z][0-9a-zA-Z-_]*$")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct GetEnvironmentOutput: AWSDecodableShape {
        /// An object containing all available details about the environment.
        public let environment: Environment?

        public init(environment: Environment? = nil) {
            self.environment = environment
        }

        private enum CodingKeys: String, CodingKey {
            case environment = "Environment"
        }
    }

    public struct LastUpdate: AWSDecodableShape {
        /// The day and time of the last update on the environment.
        public let createdAt: Date?
        /// The error that was encountered during the last update of the environment.
        public let error: UpdateError?
        /// The source of the last update to the environment. Includes internal processes by Amazon MWAA, such as an environment maintenance update.
        public let source: String?
        /// The status of the last update on the environment.
        public let status: UpdateStatus?

        public init(createdAt: Date? = nil, error: UpdateError? = nil, source: String? = nil, status: UpdateStatus? = nil) {
            self.createdAt = createdAt
            self.error = error
            self.source = source
            self.status = status
        }

        private enum CodingKeys: String, CodingKey {
            case createdAt = "CreatedAt"
            case error = "Error"
            case source = "Source"
            case status = "Status"
        }
    }

    public struct ListEnvironmentsInput: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "maxResults", location: .querystring("MaxResults")),
            AWSMemberEncoding(label: "nextToken", location: .querystring("NextToken"))
        ]

        /// The maximum number of results to retrieve per page. For example, 5 environments per page.
        public let maxResults: Int?
        /// Retrieves the next page of the results.
        public let nextToken: String?

        public init(maxResults: Int? = nil, nextToken: String? = nil) {
            self.maxResults = maxResults
            self.nextToken = nextToken
        }

        public func validate(name: String) throws {
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 2048)
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct ListEnvironmentsOutput: AWSDecodableShape {
        /// Returns a list of Amazon MWAA environments.
        public let environments: [String]
        /// Retrieves the next page of the results.
        public let nextToken: String?

        public init(environments: [String], nextToken: String? = nil) {
            self.environments = environments
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case environments = "Environments"
            case nextToken = "NextToken"
        }
    }

    public struct ListTagsForResourceInput: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "resourceArn", location: .uri("ResourceArn"))
        ]

        /// The Amazon Resource Name (ARN) of the Amazon MWAA environment. For example, arn:aws:airflow:us-east-1:123456789012:environment/MyMWAAEnvironment.
        public let resourceArn: String

        public init(resourceArn: String) {
            self.resourceArn = resourceArn
        }

        public func validate(name: String) throws {
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, max: 1224)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, min: 1)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, pattern: "^arn:aws(-[a-z]+)?:airflow:[a-z0-9\\-]+:\\d{12}:environment/\\w+")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct ListTagsForResourceOutput: AWSDecodableShape {
        /// The key-value tag pairs associated to your environment. To learn more, see Tagging Amazon Web Services resources.
        public let tags: [String: String]?

        public init(tags: [String: String]? = nil) {
            self.tags = tags
        }

        private enum CodingKeys: String, CodingKey {
            case tags = "Tags"
        }
    }

    public struct LoggingConfiguration: AWSDecodableShape {
        /// The Airflow DAG processing logs published to CloudWatch Logs and the log level.
        public let dagProcessingLogs: ModuleLoggingConfiguration?
        /// The Airflow scheduler logs published to CloudWatch Logs and the log level.
        public let schedulerLogs: ModuleLoggingConfiguration?
        /// The Airflow task logs published to CloudWatch Logs and the log level.
        public let taskLogs: ModuleLoggingConfiguration?
        /// The Airflow web server logs published to CloudWatch Logs and the log level.
        public let webserverLogs: ModuleLoggingConfiguration?
        /// The Airflow worker logs published to CloudWatch Logs and the log level.
        public let workerLogs: ModuleLoggingConfiguration?

        public init(dagProcessingLogs: ModuleLoggingConfiguration? = nil, schedulerLogs: ModuleLoggingConfiguration? = nil, taskLogs: ModuleLoggingConfiguration? = nil, webserverLogs: ModuleLoggingConfiguration? = nil, workerLogs: ModuleLoggingConfiguration? = nil) {
            self.dagProcessingLogs = dagProcessingLogs
            self.schedulerLogs = schedulerLogs
            self.taskLogs = taskLogs
            self.webserverLogs = webserverLogs
            self.workerLogs = workerLogs
        }

        private enum CodingKeys: String, CodingKey {
            case dagProcessingLogs = "DagProcessingLogs"
            case schedulerLogs = "SchedulerLogs"
            case taskLogs = "TaskLogs"
            case webserverLogs = "WebserverLogs"
            case workerLogs = "WorkerLogs"
        }
    }

    public struct LoggingConfigurationInput: AWSEncodableShape {
        /// Publishes Airflow DAG processing logs to CloudWatch Logs.
        public let dagProcessingLogs: ModuleLoggingConfigurationInput?
        /// Publishes Airflow scheduler logs to CloudWatch Logs.
        public let schedulerLogs: ModuleLoggingConfigurationInput?
        /// Publishes Airflow task logs to CloudWatch Logs.
        public let taskLogs: ModuleLoggingConfigurationInput?
        /// Publishes Airflow web server logs to CloudWatch Logs.
        public let webserverLogs: ModuleLoggingConfigurationInput?
        /// Publishes Airflow worker logs to CloudWatch Logs.
        public let workerLogs: ModuleLoggingConfigurationInput?

        public init(dagProcessingLogs: ModuleLoggingConfigurationInput? = nil, schedulerLogs: ModuleLoggingConfigurationInput? = nil, taskLogs: ModuleLoggingConfigurationInput? = nil, webserverLogs: ModuleLoggingConfigurationInput? = nil, workerLogs: ModuleLoggingConfigurationInput? = nil) {
            self.dagProcessingLogs = dagProcessingLogs
            self.schedulerLogs = schedulerLogs
            self.taskLogs = taskLogs
            self.webserverLogs = webserverLogs
            self.workerLogs = workerLogs
        }

        private enum CodingKeys: String, CodingKey {
            case dagProcessingLogs = "DagProcessingLogs"
            case schedulerLogs = "SchedulerLogs"
            case taskLogs = "TaskLogs"
            case webserverLogs = "WebserverLogs"
            case workerLogs = "WorkerLogs"
        }
    }

    public struct MetricDatum: AWSEncodableShape {
        ///  Internal only. The dimensions associated with the metric.
        public let dimensions: [Dimension]?
        ///  Internal only. The name of the metric.
        public let metricName: String
        ///  Internal only. The statistical values for the metric.
        public let statisticValues: StatisticSet?
        ///  Internal only. The time the metric data was received.
        public let timestamp: Date
        ///  Internal only. The unit used to store the metric.
        public let unit: Unit?
        ///  Internal only. The value for the metric.
        public let value: Double?

        public init(dimensions: [Dimension]? = nil, metricName: String, statisticValues: StatisticSet? = nil, timestamp: Date, unit: Unit? = nil, value: Double? = nil) {
            self.dimensions = dimensions
            self.metricName = metricName
            self.statisticValues = statisticValues
            self.timestamp = timestamp
            self.unit = unit
            self.value = value
        }

        private enum CodingKeys: String, CodingKey {
            case dimensions = "Dimensions"
            case metricName = "MetricName"
            case statisticValues = "StatisticValues"
            case timestamp = "Timestamp"
            case unit = "Unit"
            case value = "Value"
        }
    }

    public struct ModuleLoggingConfiguration: AWSDecodableShape {
        /// The Amazon Resource Name (ARN) for the CloudWatch Logs group where the Apache Airflow log type (e.g. DagProcessingLogs) is published. For example, arn:aws:logs:us-east-1:123456789012:log-group:airflow-MyMWAAEnvironment-MwaaEnvironment-DAGProcessing:*.
        public let cloudWatchLogGroupArn: String?
        /// Indicates whether the Apache Airflow log type (e.g. DagProcessingLogs) is enabled.
        public let enabled: Bool?
        /// The Apache Airflow log level for the log type (e.g. DagProcessingLogs).
        public let logLevel: LoggingLevel?

        public init(cloudWatchLogGroupArn: String? = nil, enabled: Bool? = nil, logLevel: LoggingLevel? = nil) {
            self.cloudWatchLogGroupArn = cloudWatchLogGroupArn
            self.enabled = enabled
            self.logLevel = logLevel
        }

        private enum CodingKeys: String, CodingKey {
            case cloudWatchLogGroupArn = "CloudWatchLogGroupArn"
            case enabled = "Enabled"
            case logLevel = "LogLevel"
        }
    }

    public struct ModuleLoggingConfigurationInput: AWSEncodableShape {
        /// Indicates whether to enable the Apache Airflow log type (e.g. DagProcessingLogs).
        public let enabled: Bool
        /// Defines the Apache Airflow log level (e.g. INFO) to send to CloudWatch Logs.
        public let logLevel: LoggingLevel

        public init(enabled: Bool, logLevel: LoggingLevel) {
            self.enabled = enabled
            self.logLevel = logLevel
        }

        private enum CodingKeys: String, CodingKey {
            case enabled = "Enabled"
            case logLevel = "LogLevel"
        }
    }

    public struct NetworkConfiguration: AWSEncodableShape & AWSDecodableShape {
        /// A list of security group IDs. To learn more, see Security in your VPC on Amazon MWAA.
        public let securityGroupIds: [String]?
        /// A list of subnet IDs. To learn more, see About networking on Amazon MWAA.
        public let subnetIds: [String]?

        public init(securityGroupIds: [String]? = nil, subnetIds: [String]? = nil) {
            self.securityGroupIds = securityGroupIds
            self.subnetIds = subnetIds
        }

        public func validate(name: String) throws {
            try self.securityGroupIds?.forEach {
                try validate($0, name: "securityGroupIds[]", parent: name, max: 1024)
                try validate($0, name: "securityGroupIds[]", parent: name, min: 1)
                try validate($0, name: "securityGroupIds[]", parent: name, pattern: "^sg-[a-zA-Z0-9\\-._]+$")
            }
            try self.validate(self.securityGroupIds, name: "securityGroupIds", parent: name, max: 5)
            try self.validate(self.securityGroupIds, name: "securityGroupIds", parent: name, min: 1)
            try self.subnetIds?.forEach {
                try validate($0, name: "subnetIds[]", parent: name, max: 1024)
                try validate($0, name: "subnetIds[]", parent: name, min: 1)
                try validate($0, name: "subnetIds[]", parent: name, pattern: "^subnet-[a-zA-Z0-9\\-._]+$")
            }
            try self.validate(self.subnetIds, name: "subnetIds", parent: name, max: 2)
            try self.validate(self.subnetIds, name: "subnetIds", parent: name, min: 2)
        }

        private enum CodingKeys: String, CodingKey {
            case securityGroupIds = "SecurityGroupIds"
            case subnetIds = "SubnetIds"
        }
    }

    public struct PublishMetricsInput: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "environmentName", location: .uri("EnvironmentName"))
        ]

        ///  Internal only. The name of the environment.
        public let environmentName: String
        ///  Internal only. Publishes metrics to Amazon CloudWatch. To learn more about the metrics published to Amazon CloudWatch, see Amazon MWAA performance metrics in Amazon CloudWatch.
        public let metricData: [MetricDatum]

        public init(environmentName: String, metricData: [MetricDatum]) {
            self.environmentName = environmentName
            self.metricData = metricData
        }

        public func validate(name: String) throws {
            try self.validate(self.environmentName, name: "environmentName", parent: name, max: 80)
            try self.validate(self.environmentName, name: "environmentName", parent: name, min: 1)
            try self.validate(self.environmentName, name: "environmentName", parent: name, pattern: "^[a-zA-Z][0-9a-zA-Z-_]*$")
        }

        private enum CodingKeys: String, CodingKey {
            case metricData = "MetricData"
        }
    }

    public struct PublishMetricsOutput: AWSDecodableShape {
        public init() {}
    }

    public struct StatisticSet: AWSEncodableShape {
        ///  Internal only. The maximum value of the sample set.
        public let maximum: Double?
        ///  Internal only. The minimum value of the sample set.
        public let minimum: Double?
        ///  Internal only. The number of samples used for the statistic set.
        public let sampleCount: Int?
        ///  Internal only. The sum of values for the sample set.
        public let sum: Double?

        public init(maximum: Double? = nil, minimum: Double? = nil, sampleCount: Int? = nil, sum: Double? = nil) {
            self.maximum = maximum
            self.minimum = minimum
            self.sampleCount = sampleCount
            self.sum = sum
        }

        private enum CodingKeys: String, CodingKey {
            case maximum = "Maximum"
            case minimum = "Minimum"
            case sampleCount = "SampleCount"
            case sum = "Sum"
        }
    }

    public struct TagResourceInput: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "resourceArn", location: .uri("ResourceArn"))
        ]

        /// The Amazon Resource Name (ARN) of the Amazon MWAA environment. For example, arn:aws:airflow:us-east-1:123456789012:environment/MyMWAAEnvironment.
        public let resourceArn: String
        /// The key-value tag pairs you want to associate to your environment. For example, "Environment": "Staging". To learn more, see Tagging Amazon Web Services resources.
        public let tags: [String: String]

        public init(resourceArn: String, tags: [String: String]) {
            self.resourceArn = resourceArn
            self.tags = tags
        }

        public func validate(name: String) throws {
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, max: 1224)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, min: 1)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, pattern: "^arn:aws(-[a-z]+)?:airflow:[a-z0-9\\-]+:\\d{12}:environment/\\w+")
            try self.tags.forEach {
                try validate($0.key, name: "tags.key", parent: name, max: 128)
                try validate($0.key, name: "tags.key", parent: name, min: 1)
                try validate($0.key, name: "tags.key", parent: name, pattern: "^([\\p{L}\\p{Z}\\p{N}_.:/=+\\-@]*)$")
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, max: 256)
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, min: 1)
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, pattern: "^([\\p{L}\\p{Z}\\p{N}_.:/=+\\-@]*)$")
            }
            try self.validate(self.tags, name: "tags", parent: name, max: 50)
            try self.validate(self.tags, name: "tags", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case tags = "Tags"
        }
    }

    public struct TagResourceOutput: AWSDecodableShape {
        public init() {}
    }

    public struct UntagResourceInput: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "resourceArn", location: .uri("ResourceArn")),
            AWSMemberEncoding(label: "tagKeys", location: .querystring("tagKeys"))
        ]

        /// The Amazon Resource Name (ARN) of the Amazon MWAA environment. For example, arn:aws:airflow:us-east-1:123456789012:environment/MyMWAAEnvironment.
        public let resourceArn: String
        /// The key-value tag pair you want to remove. For example, "Environment": "Staging".
        public let tagKeys: [String]

        public init(resourceArn: String, tagKeys: [String]) {
            self.resourceArn = resourceArn
            self.tagKeys = tagKeys
        }

        public func validate(name: String) throws {
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, max: 1224)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, min: 1)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, pattern: "^arn:aws(-[a-z]+)?:airflow:[a-z0-9\\-]+:\\d{12}:environment/\\w+")
            try self.tagKeys.forEach {
                try validate($0, name: "tagKeys[]", parent: name, max: 128)
                try validate($0, name: "tagKeys[]", parent: name, min: 1)
                try validate($0, name: "tagKeys[]", parent: name, pattern: "^([\\p{L}\\p{Z}\\p{N}_.:/=+\\-@]*)$")
            }
            try self.validate(self.tagKeys, name: "tagKeys", parent: name, max: 50)
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct UntagResourceOutput: AWSDecodableShape {
        public init() {}
    }

    public struct UpdateEnvironmentInput: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "name", location: .uri("Name"))
        ]

        /// A list of key-value pairs containing the Apache Airflow configuration options you want to attach to your environment. To learn more, see Apache Airflow configuration options.
        public let airflowConfigurationOptions: [String: String]?
        /// The Apache Airflow version for your environment. If no value is specified, defaults to the latest version. Valid values: 1.10.12, 2.0.2, and 2.2.2.
        public let airflowVersion: String?
        /// The relative path to the DAGs folder on your Amazon S3 bucket. For example, dags. To learn more, see Adding or updating DAGs.
        public let dagS3Path: String?
        /// The environment class type. Valid values: mw1.small, mw1.medium, mw1.large. To learn more, see Amazon MWAA environment class.
        public let environmentClass: String?
        /// The Amazon Resource Name (ARN) of the execution role in IAM that allows MWAA to access Amazon Web Services resources in your environment. For example, arn:aws:iam::123456789:role/my-execution-role. To learn more, see Amazon MWAA Execution role.
        public let executionRoleArn: String?
        /// The Apache Airflow log types to send to CloudWatch Logs.
        public let loggingConfiguration: LoggingConfigurationInput?
        /// The maximum number of workers that you want to run in your environment. MWAA scales the number of Apache Airflow workers up to the number you specify in the MaxWorkers field. For example, 20. When there are no more tasks running, and no more in the queue, MWAA disposes of the extra workers leaving the one worker that is included with your environment, or the number you specify in MinWorkers.
        public let maxWorkers: Int?
        /// The minimum number of workers that you want to run in your environment. MWAA scales the number of Apache Airflow workers up to the number you specify in the MaxWorkers field. When there are no more tasks running, and no more in the queue, MWAA disposes of the extra workers leaving the worker count you specify in the MinWorkers field. For example, 2.
        public let minWorkers: Int?
        /// The name of your Amazon MWAA environment. For example, MyMWAAEnvironment.
        public let name: String
        /// The VPC networking components used to secure and enable network traffic between the Amazon Web Services resources for your environment. To learn more, see About networking on Amazon MWAA.
        public let networkConfiguration: UpdateNetworkConfigurationInput?
        /// The version of the plugins.zip file on your Amazon S3 bucket. A version must be specified each time a plugins.zip file is updated. To learn more, see How S3 Versioning works.
        public let pluginsS3ObjectVersion: String?
        /// The relative path to the plugins.zip file on your Amazon S3 bucket. For example, plugins.zip. If specified, then the plugins.zip version is required. To learn more, see Installing custom plugins.
        public let pluginsS3Path: String?
        /// The version of the requirements.txt file on your Amazon S3 bucket. A version must be specified each time a requirements.txt file is updated. To learn more, see How S3 Versioning works.
        public let requirementsS3ObjectVersion: String?
        /// The relative path to the requirements.txt file on your Amazon S3 bucket. For example, requirements.txt. If specified, then a file version is required. To learn more, see Installing Python dependencies.
        public let requirementsS3Path: String?
        /// The number of Apache Airflow schedulers to run in your Amazon MWAA environment.
        public let schedulers: Int?
        /// The Amazon Resource Name (ARN) of the Amazon S3 bucket where your DAG code and supporting files are stored. For example, arn:aws:s3:::my-airflow-bucket-unique-name. To learn more, see Create an Amazon S3 bucket for Amazon MWAA.
        public let sourceBucketArn: String?
        /// The Apache Airflow Web server access mode. To learn more, see Apache Airflow access modes.
        public let webserverAccessMode: WebserverAccessMode?
        /// The day and time of the week in Coordinated Universal Time (UTC) 24-hour standard time to start weekly maintenance updates of your environment in the following format: DAY:HH:MM. For example: TUE:03:30. You can specify a start time in 30 minute increments only.
        public let weeklyMaintenanceWindowStart: String?

        public init(airflowConfigurationOptions: [String: String]? = nil, airflowVersion: String? = nil, dagS3Path: String? = nil, environmentClass: String? = nil, executionRoleArn: String? = nil, loggingConfiguration: LoggingConfigurationInput? = nil, maxWorkers: Int? = nil, minWorkers: Int? = nil, name: String, networkConfiguration: UpdateNetworkConfigurationInput? = nil, pluginsS3ObjectVersion: String? = nil, pluginsS3Path: String? = nil, requirementsS3ObjectVersion: String? = nil, requirementsS3Path: String? = nil, schedulers: Int? = nil, sourceBucketArn: String? = nil, webserverAccessMode: WebserverAccessMode? = nil, weeklyMaintenanceWindowStart: String? = nil) {
            self.airflowConfigurationOptions = airflowConfigurationOptions
            self.airflowVersion = airflowVersion
            self.dagS3Path = dagS3Path
            self.environmentClass = environmentClass
            self.executionRoleArn = executionRoleArn
            self.loggingConfiguration = loggingConfiguration
            self.maxWorkers = maxWorkers
            self.minWorkers = minWorkers
            self.name = name
            self.networkConfiguration = networkConfiguration
            self.pluginsS3ObjectVersion = pluginsS3ObjectVersion
            self.pluginsS3Path = pluginsS3Path
            self.requirementsS3ObjectVersion = requirementsS3ObjectVersion
            self.requirementsS3Path = requirementsS3Path
            self.schedulers = schedulers
            self.sourceBucketArn = sourceBucketArn
            self.webserverAccessMode = webserverAccessMode
            self.weeklyMaintenanceWindowStart = weeklyMaintenanceWindowStart
        }

        public func validate(name: String) throws {
            try self.airflowConfigurationOptions?.forEach {
                try validate($0.key, name: "airflowConfigurationOptions.key", parent: name, max: 64)
                try validate($0.key, name: "airflowConfigurationOptions.key", parent: name, min: 1)
                try validate($0.key, name: "airflowConfigurationOptions.key", parent: name, pattern: "^[a-z]+([a-z0-9._]*[a-z0-9_]+)?$")
                try validate($0.value, name: "airflowConfigurationOptions[\"\($0.key)\"]", parent: name, max: 65536)
                try validate($0.value, name: "airflowConfigurationOptions[\"\($0.key)\"]", parent: name, min: 1)
                try validate($0.value, name: "airflowConfigurationOptions[\"\($0.key)\"]", parent: name, pattern: "^[ -~]+$")
            }
            try self.validate(self.airflowVersion, name: "airflowVersion", parent: name, max: 32)
            try self.validate(self.airflowVersion, name: "airflowVersion", parent: name, min: 1)
            try self.validate(self.airflowVersion, name: "airflowVersion", parent: name, pattern: "^[0-9a-z.]+$")
            try self.validate(self.dagS3Path, name: "dagS3Path", parent: name, max: 1024)
            try self.validate(self.dagS3Path, name: "dagS3Path", parent: name, min: 1)
            try self.validate(self.dagS3Path, name: "dagS3Path", parent: name, pattern: ".*")
            try self.validate(self.environmentClass, name: "environmentClass", parent: name, max: 1024)
            try self.validate(self.environmentClass, name: "environmentClass", parent: name, min: 1)
            try self.validate(self.executionRoleArn, name: "executionRoleArn", parent: name, max: 1224)
            try self.validate(self.executionRoleArn, name: "executionRoleArn", parent: name, min: 1)
            try self.validate(self.executionRoleArn, name: "executionRoleArn", parent: name, pattern: "^arn:aws(-[a-z]+)?:iam::\\d{12}:role/?[a-zA-Z_0-9+=,.@\\-_/]+$")
            try self.validate(self.maxWorkers, name: "maxWorkers", parent: name, min: 1)
            try self.validate(self.minWorkers, name: "minWorkers", parent: name, min: 1)
            try self.validate(self.name, name: "name", parent: name, max: 80)
            try self.validate(self.name, name: "name", parent: name, min: 1)
            try self.validate(self.name, name: "name", parent: name, pattern: "^[a-zA-Z][0-9a-zA-Z-_]*$")
            try self.networkConfiguration?.validate(name: "\(name).networkConfiguration")
            try self.validate(self.pluginsS3ObjectVersion, name: "pluginsS3ObjectVersion", parent: name, max: 1024)
            try self.validate(self.pluginsS3ObjectVersion, name: "pluginsS3ObjectVersion", parent: name, min: 1)
            try self.validate(self.pluginsS3Path, name: "pluginsS3Path", parent: name, max: 1024)
            try self.validate(self.pluginsS3Path, name: "pluginsS3Path", parent: name, min: 1)
            try self.validate(self.pluginsS3Path, name: "pluginsS3Path", parent: name, pattern: ".*")
            try self.validate(self.requirementsS3ObjectVersion, name: "requirementsS3ObjectVersion", parent: name, max: 1024)
            try self.validate(self.requirementsS3ObjectVersion, name: "requirementsS3ObjectVersion", parent: name, min: 1)
            try self.validate(self.requirementsS3Path, name: "requirementsS3Path", parent: name, max: 1024)
            try self.validate(self.requirementsS3Path, name: "requirementsS3Path", parent: name, min: 1)
            try self.validate(self.requirementsS3Path, name: "requirementsS3Path", parent: name, pattern: ".*")
            try self.validate(self.schedulers, name: "schedulers", parent: name, max: 5)
            try self.validate(self.sourceBucketArn, name: "sourceBucketArn", parent: name, max: 1224)
            try self.validate(self.sourceBucketArn, name: "sourceBucketArn", parent: name, min: 1)
            try self.validate(self.sourceBucketArn, name: "sourceBucketArn", parent: name, pattern: "^arn:aws(-[a-z]+)?:s3:::[a-z0-9.\\-]+$")
            try self.validate(self.weeklyMaintenanceWindowStart, name: "weeklyMaintenanceWindowStart", parent: name, max: 9)
            try self.validate(self.weeklyMaintenanceWindowStart, name: "weeklyMaintenanceWindowStart", parent: name, min: 1)
            try self.validate(self.weeklyMaintenanceWindowStart, name: "weeklyMaintenanceWindowStart", parent: name, pattern: "(MON|TUE|WED|THU|FRI|SAT|SUN):([01]\\d|2[0-3]):(00|30)")
        }

        private enum CodingKeys: String, CodingKey {
            case airflowConfigurationOptions = "AirflowConfigurationOptions"
            case airflowVersion = "AirflowVersion"
            case dagS3Path = "DagS3Path"
            case environmentClass = "EnvironmentClass"
            case executionRoleArn = "ExecutionRoleArn"
            case loggingConfiguration = "LoggingConfiguration"
            case maxWorkers = "MaxWorkers"
            case minWorkers = "MinWorkers"
            case networkConfiguration = "NetworkConfiguration"
            case pluginsS3ObjectVersion = "PluginsS3ObjectVersion"
            case pluginsS3Path = "PluginsS3Path"
            case requirementsS3ObjectVersion = "RequirementsS3ObjectVersion"
            case requirementsS3Path = "RequirementsS3Path"
            case schedulers = "Schedulers"
            case sourceBucketArn = "SourceBucketArn"
            case webserverAccessMode = "WebserverAccessMode"
            case weeklyMaintenanceWindowStart = "WeeklyMaintenanceWindowStart"
        }
    }

    public struct UpdateEnvironmentOutput: AWSDecodableShape {
        /// The Amazon Resource Name (ARN) of the Amazon MWAA environment. For example, arn:aws:airflow:us-east-1:123456789012:environment/MyMWAAEnvironment.
        public let arn: String?

        public init(arn: String? = nil) {
            self.arn = arn
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "Arn"
        }
    }

    public struct UpdateError: AWSDecodableShape {
        /// The error code that corresponds to the error with the last update.
        public let errorCode: String?
        /// The error message that corresponds to the error code.
        public let errorMessage: String?

        public init(errorCode: String? = nil, errorMessage: String? = nil) {
            self.errorCode = errorCode
            self.errorMessage = errorMessage
        }

        private enum CodingKeys: String, CodingKey {
            case errorCode = "ErrorCode"
            case errorMessage = "ErrorMessage"
        }
    }

    public struct UpdateNetworkConfigurationInput: AWSEncodableShape {
        /// A list of security group IDs. A security group must be attached to the same VPC as the subnets. To learn more, see Security in your VPC on Amazon MWAA.
        public let securityGroupIds: [String]

        public init(securityGroupIds: [String]) {
            self.securityGroupIds = securityGroupIds
        }

        public func validate(name: String) throws {
            try self.securityGroupIds.forEach {
                try validate($0, name: "securityGroupIds[]", parent: name, max: 1024)
                try validate($0, name: "securityGroupIds[]", parent: name, min: 1)
                try validate($0, name: "securityGroupIds[]", parent: name, pattern: "^sg-[a-zA-Z0-9\\-._]+$")
            }
            try self.validate(self.securityGroupIds, name: "securityGroupIds", parent: name, max: 5)
            try self.validate(self.securityGroupIds, name: "securityGroupIds", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case securityGroupIds = "SecurityGroupIds"
        }
    }
}

// MARK: - Errors

/// Error enum for MWAA
public struct MWAAErrorType: AWSErrorType {
    enum Code: String {
        case accessDeniedException = "AccessDeniedException"
        case internalServerException = "InternalServerException"
        case resourceNotFoundException = "ResourceNotFoundException"
        case validationException = "ValidationException"
    }

    private let error: Code
    public let context: AWSErrorContext?

    /// initialize MWAA
    public init?(errorCode: String, context: AWSErrorContext) {
        guard let error = Code(rawValue: errorCode) else { return nil }
        self.error = error
        self.context = context
    }

    internal init(_ error: Code) {
        self.error = error
        self.context = nil
    }

    /// return error code string
    public var errorCode: String { self.error.rawValue }

    /// Access to the Apache Airflow Web UI or CLI has been denied due to insufficient permissions. To learn more, see Accessing an Amazon MWAA environment.
    public static var accessDeniedException: Self { .init(.accessDeniedException) }
    /// InternalServerException: An internal error has occurred.
    public static var internalServerException: Self { .init(.internalServerException) }
    /// ResourceNotFoundException: The resource is not available.
    public static var resourceNotFoundException: Self { .init(.resourceNotFoundException) }
    /// ValidationException: The provided input is not valid.
    public static var validationException: Self { .init(.validationException) }
}

extension MWAAErrorType: Equatable {
    public static func == (lhs: MWAAErrorType, rhs: MWAAErrorType) -> Bool {
        lhs.error == rhs.error
    }
}

extension MWAAErrorType: CustomStringConvertible {
    public var description: String {
        return "\(self.error.rawValue): \(self.message ?? "")"
    }
}
